# -*- coding: utf-8 -*-
import requests
import json
import aliyunsdkcore.client
import aliyunsdkcore.request
import io
from pydub import AudioSegment
from pydub.playback import play
import os

class AliTTS:
    """阿里云文字转语音 (TTS) 类。"""
    def __init__(self):
        self.__appkey, self.__access_id, self.__access_key = self._get_ali_keys_from_settings()
        if not all([self.__appkey, self.__access_id, self.__access_key]):
            raise ValueError("缺少阿里云TTS凭据，请检查settings.txt。")

        self.__token = self._get_sts_token()
        if not self.__token:
            raise ConnectionError("无法获取阿里云STS Token。")

    def _get_ali_keys_from_settings(self):
        """从settings.txt文件中获取阿里云语音服务的凭据（appkey, access_id, access_key）。"""
        settings_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'settings.txt')
        try:
            with open(settings_path, 'r', encoding='utf-8') as f:
                settings = json.load(f)
                app_key = settings.get("Ali_voice_app_key")
                access_id = settings.get("Ali_voice_access_id")
                access_key = settings.get("Ali_voice_access_key")
                return app_key, access_id, access_key
        except Exception as e:
            return None, None, None

    def _get_sts_token(self):
        """获取阿里云STS Token，用于访问语音服务。"""
        try:
            client = aliyunsdkcore.client.AcsClient(self.__access_id, self.__access_key, "cn-shanghai")
            request = aliyunsdkcore.request.CommonRequest()
            request.set_method('POST')
            request.set_domain('nls-meta.cn-shanghai.aliyuncs.com')
            request.set_version('2019-02-28')
            request.set_action_name('CreateToken')
            response = client.do_action_with_exception(request)
            jss = json.loads(response)
            if 'Token' in jss and 'Id' in jss['Token']:
                token = jss['Token']['Id']
                return token
            else:
                return None
        except Exception as e:
            return None
    #Aitong
    def synthesize_and_play(self, text: str, voice: str = "zhistella", sample_rate: int = 16000) -> bool:
        """
        使用GET请求调用阿里云TTS服务，并直接播放音频。

        Args:
            text (str): 要转换为语音的文本。
            voice (str, optional): 发音人。默认为 "zhistella"。
            sample_rate (int, optional): 音频采样率。默认为 16000。

        Returns:
            bool: 成功返回True，失败返回False。
        """
        if not self.__token:
            return False

        URL = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts"
        params = {
            "appkey": self.__appkey,
            "token": self.__token,
            "text": text,
            "format": "mp3", # 阿里云TTS GET接口只支持mp3
            "sample_rate": sample_rate,
            "voice": voice
        }

        try:
            response = requests.get(URL, params=params, stream=True)
            response.raise_for_status()

            content_type = response.headers.get("Content-Type")
            if content_type == "audio/mpeg":
                self._play_mp3_data(response.content)
                return True
            else:
                return False

        except requests.exceptions.RequestException as e:
            return False
        except Exception as e:
            return False

    def _play_mp3_data(self, mp3_data: bytes):
        """播放MP3字节数据。"""
        try:
            audio = AudioSegment.from_file(io.BytesIO(mp3_data), format="mp3")
            play(audio)
        except Exception as e:
            pass # 移除提示信息

    def __del__(self):
        """析构函数，确保资源被释放。"""
        pass

# 示例用法
if __name__ == '__main__':
    try:
        tts_agent = AliTTS()
        
        text_to_play_1 = "你好，这是一个使用GET请求的阿里云TTS测试。欢迎使用阿里云智能语音服务。"
        tts_agent.synthesize_and_play(text_to_play_1)

        import time
        time.sleep(1)

        text_to_play_2 = "现在测试第二条语音，使用不同的发音人，例如艾琪。"
        tts_agent.synthesize_and_play(text_to_play_2, voice="Aiqi")

    except (ValueError, ConnectionError) as e:
        pass # 移除提示信息
    except Exception as e:
        pass # 移除提示信息
